package com.kartoshka.utils 
{
	import flash.utils.describeType;
	import flash.utils.getQualifiedClassName;
	import flash.utils.Dictionary;

	/**
	 * @author Alexander Zats, 2009
	 */
	public class ClassUtil 
	{
		private static const _typesHash : Dictionary = new Dictionary( true );

		public static const ENUMERATE_RETURNS_OBJECT : int = 1;
		public static const ENUMERATE_RETURNS_ARRAY_OF_VALUES : int = 2;
		public static const ENUMERATE_RETURNS_ARRAY_OF_KEYS : int = 2;

		public static function enumeratePublicConstants( classRef : Class, returnType : int = 1 ) : Object
		{
			var qName : String = getQualifiedClassName( classRef );
			if ( ! _typesHash.hasOwnProperty( qName ) ) _typesHash[ qName ] = describeType( classRef );
			var type : XML = _typesHash[ qName ];

			var answer : Object;
			var constant : XML;
			switch ( returnType )
			{
				case ENUMERATE_RETURNS_OBJECT:
					answer = {};
					for each ( constant in type[ "constant" ] )
					{
						answer[ constant[ "@name" ] ] = classRef[ constant[ "@name" ] ];
					}
					break;
				case ENUMERATE_RETURNS_ARRAY_OF_KEYS:
					answer = [];
					for each ( constant in type[ "constant" ] )
					{
						answer[ ( answer as Array ).length ] = constant[ "@name" ];
					}
					break;
				case ENUMERATE_RETURNS_ARRAY_OF_VALUES:
					answer = [];
					for each ( constant in type[ "constant" ] )
					{
						answer[ ( answer as Array ).length ] = classRef[ constant[ "@name" ] ];
					}
					break;
			}
			return answer;
		}

		public static function isSingleton( classRef : Class ) : Boolean
		{
			var qName : String = getQualifiedClassName( classRef );
			if ( ! _typesHash.hasOwnProperty( qName ) ) _typesHash[ qName ] = describeType( classRef );
			var type : XML = _typesHash[ qName ];
			
			if ( ( type.hasOwnProperty( "accessor" ) && ( type.accessor.( @name == "instance" ) as XMLList ).length( ) && ( type.accessor.( @name == "instance" ) as XMLList )[ "@type" ] == qName ) || ( type.hasOwnProperty( "method" ) && ( type.method.( @name == "getInstance" ) as XMLList ).length( ) && ( type.method.( @name == "getInstance" ) as XMLList )[ "@returnType" ] == qName ) )
			{
				return true;
			}
			return false;
		}
	}
}
